# 1.4三次样条插值

x = [1, 2, 4, 5]
y = [1, 3, 4, 2]
xx = 3
n = len(x)-1  # n = 3
h = []
for i in range(n):
    h.append(x[i + 1] - x[i])
# 使用第二种边界条件，计算alpha、beta
alpha = []
beta = []
for i in range(n + 1):
    if (i == 0):
        alpha.append(1)
        beta.append(3 / h[0] * (y[1] - y[0]))
        continue
    if(i == n):
        alpha.append(0)
        beta.append(3 / h[n - 1] * (y[n] - y[n - 1]))
        continue
    alpha.append(h[i - 1] / (h[i - 1] + h[i]))
    tmp1 = (1 - alpha[i]) / h[i - 1] * (y[i] - y[i - 1])
    tmp2 = alpha[i] / h[i] * (y[i + 1] - y[i])
    beta.append(3 * (tmp1 + tmp2))
# print(alpha, beta)
# 计算a、b
a = [-alpha[0]/2]
b = [beta[0]/2]
for i in range(1, n + 1):
    a.append(-alpha[i] / (2 + (1 - alpha[i]) * alpha[i - 1]))
    tmp1 = beta[i] - (1 - alpha[i]) * b[i - 1]
    tmp2 = 2 + (1 - alpha[i]) * a[i - 1]
    b.append(tmp1 / tmp2)

# 计算m
m = [b[n]] * (n + 1)
for i in range(n - 1, -1, -1):
    m[i] = a[i] * m[i + 1] + b[i]
# print(m)

i = 0
while (xx > x[i]):
    i += 1
i -= 1
tmp1 = (1 + 2 * (xx - x[i]) / (x[i + 1] - x[i])) * \
    ((xx - x[i + 1]) / (x[i] - x[i + 1])) ** 2
tmp2 = (1 + 2 * (xx - x[i + 1]) / (x[i] - x[i + 1])) * \
    ((xx - x[i]) / (x[i + 1] - x[i])) ** 2
tmp3 = (xx - x[i]) * ((xx - x[i + 1]) / (x[i] - x[i + 1])) ** 2
tmp4 = (xx - x[i+1]) * ((xx - x[i]) / (x[i+1] - x[i])) ** 2
yy = tmp1 * y[i] + tmp2 * y[i + 1] + tmp3 * m[i] + tmp4 * m[i + 1]

print("y_predict= %.4f" % yy)
